#ifndef _WX_CMDLINE_H_
#define _WX_CMDLINE_H_

#include "wx/defs.h"

#include "wx/string.h"
#include "wx/arrstr.h"

#if wxUSE_CMDLINE_PARSER

class wxDateTime;

enum {
  wxCMD_LINE_OPTION_MANDATORY = 0x01, // this option must be given
  wxCMD_LINE_PARAM_OPTIONAL   = 0x02, // the parameter may be omitted
  wxCMD_LINE_PARAM_MULTIPLE   = 0x04, // the parameter may be repeated
  wxCMD_LINE_OPTION_HELP      = 0x08, // this option is a help request
  wxCMD_LINE_NEEDS_SEPARATOR  = 0x10  // must have sep before the value
};

// an option value or parameter may be a string (the most common case), a
// number or a date
enum wxCmdLineParamType {
  wxCMD_LINE_VAL_STRING,  // should be 0 (default)
  wxCMD_LINE_VAL_NUMBER,
  wxCMD_LINE_VAL_DATE,
  wxCMD_LINE_VAL_NONE
};

// for constructing the cmd line description using Init()
enum wxCmdLineEntryType {
  wxCMD_LINE_SWITCH,
  wxCMD_LINE_OPTION,
  wxCMD_LINE_PARAM,
  wxCMD_LINE_NONE         // to terminate the list
};

// ----------------------------------------------------------------------------
// wxCmdLineEntryDesc is a description of one command line
// switch/option/parameter
// ----------------------------------------------------------------------------

struct wxCmdLineEntryDesc {
  wxCmdLineEntryType kind;
  const wxChar *shortName;
  const wxChar *longName;
  const wxChar *description;
  wxCmdLineParamType type;
  int flags;
};

class wxCmdLineParser {
  public:
    // ctors and initializers
    // ----------------------

    // default ctor or ctor giving the cmd line in either Unix or Win form
    wxCmdLineParser() { Init(); }
    wxCmdLineParser( int argc, char **argv ) { Init(); SetCmdLine( argc, argv ); }
    wxCmdLineParser( int argc, wxChar **argv ) { Init(); SetCmdLine( argc, argv ); }
    wxCmdLineParser( const wxString& cmdline ) { Init(); SetCmdLine( cmdline ); }
    wxCmdLineParser( const wxCmdLineEntryDesc *desc ) { Init(); SetDesc( desc ); }
    wxCmdLineParser( const wxCmdLineEntryDesc *desc, int argc, char **argv ) { Init(); SetCmdLine( argc, argv ); SetDesc( desc ); }
    wxCmdLineParser( const wxCmdLineEntryDesc *desc, int argc, wxChar **argv ) { Init(); SetCmdLine( argc, argv ); SetDesc( desc ); }
    wxCmdLineParser( const wxCmdLineEntryDesc *desc, const wxString& cmdline ) { Init(); SetCmdLine( cmdline ); SetDesc( desc ); }

    // set cmd line to parse after using one of the ctors which don't do it
    void SetCmdLine( int argc, char **argv );
    void SetCmdLine( int argc, wxChar **argv );
    void SetCmdLine( const wxString& cmdline );
    ~wxCmdLineParser();
    void SetSwitchChars( const wxString& switchChars );
    void EnableLongOptions( bool enable = true );
    void DisableLongOptions() { EnableLongOptions( false ); }
    bool AreLongOptionsEnabled();
    void SetLogo( const wxString& logo );
    void SetDesc( const wxCmdLineEntryDesc *desc );
    void AddSwitch( const wxString& name, const wxString& lng = wxEmptyString,
                    const wxString& desc = wxEmptyString,
                    int flags = 0 );
    void AddOption( const wxString& name, const wxString& lng = wxEmptyString,
                    const wxString& desc = wxEmptyString,
                    wxCmdLineParamType type = wxCMD_LINE_VAL_STRING,
                    int flags = 0 );
    void AddParam( const wxString& desc = wxEmptyString,
                   wxCmdLineParamType type = wxCMD_LINE_VAL_STRING,
                   int flags = 0 );
    int Parse( bool showUsage = true );
    void Usage();
    bool Found( const wxString& name ) const;
    bool Found( const wxString& name, wxString *value ) const;
    bool Found( const wxString& name, long *value ) const;
    bool Found( const wxString& name, wxDateTime *value ) const;
    size_t GetParamCount() const;
    wxString GetParam( size_t n = 0u ) const;
    void Reset();

    // break down the command line in arguments
    static wxArrayString ConvertStringToArgs( const wxChar *cmdline );

  private:
    // get usage string
    wxString GetUsageString();

    // common part of all ctors
    void Init();

    struct wxCmdLineParserData *m_data;

    DECLARE_NO_COPY_CLASS( wxCmdLineParser )
};

#else // !wxUSE_CMDLINE_PARSER

// this function is always available (even if !wxUSE_CMDLINE_PARSER) because it
// is used by wxWin itself under Windows
class wxCmdLineParser {
  public:
    static wxArrayString ConvertStringToArgs( const wxChar *cmdline );
};

#endif // wxUSE_CMDLINE_PARSER/!wxUSE_CMDLINE_PARSER

#endif // _WX_CMDLINE_H_

